#include "serializer/io.h"
#include "serializer/traits.h"

#include <gtest/gtest.h>
#include <stlcompat/span.h>

#include <array>
#include <cstddef>
#include <stdexcept>
#include <string>
#include <string_view>
#include <vector>

using namespace serializer;

/**
 * vector_writer 基础功能测试
 */
class VectorWriterTest : public ::testing::Test
{
protected:
    vector_writer writer_;
};

/**
 * 测试 vector_writer 的基本写入功能
 */
TEST_F(VectorWriterTest, basic_write_operations)
{
    // 测试写入原始字节
    std::array<std::byte, 4> data{
        std::byte{0x01}, std::byte{0x02}, std::byte{0x03}, std::byte{0x04}};
    writer_.write_bytes(data.data(), data.size());

    EXPECT_EQ(writer_.bytes_written(), 4);
    EXPECT_EQ(writer_.position(), 4);
    EXPECT_TRUE(writer_.can_write(1000)); // 内存写入器总是可以写入

    const auto & buffer = writer_.data();
    EXPECT_EQ(buffer.size(), 4);
    EXPECT_EQ(buffer[0], std::byte{0x01});
    EXPECT_EQ(buffer[1], std::byte{0x02});
    EXPECT_EQ(buffer[2], std::byte{0x03});
    EXPECT_EQ(buffer[3], std::byte{0x04});
}

/**
 * 测试 vector_writer 的 span 写入功能
 */
TEST_F(VectorWriterTest, span_write_operations)
{
    std::array<std::byte, 3> data{std::byte{0xAA}, std::byte{0xBB}, std::byte{0xCC}};
    kp::span<const std::byte> span_data(data.data(), data.size());

    writer_.write_bytes(span_data);

    EXPECT_EQ(writer_.bytes_written(), 3);
    const auto & buffer = writer_.data();
    EXPECT_EQ(buffer[0], std::byte{0xAA});
    EXPECT_EQ(buffer[1], std::byte{0xBB});
    EXPECT_EQ(buffer[2], std::byte{0xCC});
}

/**
 * 测试 vector_writer 的字符串写入功能
 */
TEST_F(VectorWriterTest, string_write_operations)
{
    std::string_view test_string = "Hello, World!";
    writer_.write_string_view(test_string);

    EXPECT_EQ(writer_.bytes_written(), test_string.size());
    EXPECT_EQ(writer_.position(), test_string.size());

    // 验证写入的内容
    const auto & buffer = writer_.data();
    for (size_t i = 0; i < test_string.size(); ++i)
    {
        EXPECT_EQ(static_cast<char>(buffer[i]), test_string[i]);
    }
}

/**
 * 测试 vector_writer 的清空功能
 */
TEST_F(VectorWriterTest, clear_functionality)
{
    // 先写入一些数据
    std::array<std::byte, 2> data{std::byte{0x11}, std::byte{0x22}};
    writer_.write_bytes(data.data(), data.size());

    EXPECT_EQ(writer_.bytes_written(), 2);
    EXPECT_EQ(writer_.position(), 2);

    // 清空
    writer_.clear();

    EXPECT_EQ(writer_.bytes_written(), 0);
    EXPECT_EQ(writer_.position(), 0);
    EXPECT_TRUE(writer_.data().empty());
}

/**
 * 测试 vector_writer 的错误处理
 */
TEST_F(VectorWriterTest, error_handling)
{
    // 测试空指针写入
    EXPECT_THROW(writer_.write_bytes(nullptr, 5), std::runtime_error);

    // 测试空指针但大小为0的情况（应该成功）
    EXPECT_NO_THROW(writer_.write_bytes(nullptr, 0));
}

/**
 * 测试 vector_writer 的连续写入
 */
TEST_F(VectorWriterTest, sequential_writes)
{
    // 第一次写入
    std::array<std::byte, 2> data1{std::byte{0x01}, std::byte{0x02}};
    writer_.write_bytes(data1.data(), data1.size());

    // 第二次写入
    std::array<std::byte, 3> data2{std::byte{0x03}, std::byte{0x04}, std::byte{0x05}};
    writer_.write_bytes(data2.data(), data2.size());

    EXPECT_EQ(writer_.bytes_written(), 5);
    EXPECT_EQ(writer_.position(), 5);

    const auto & buffer = writer_.data();
    EXPECT_EQ(buffer[0], std::byte{0x01});
    EXPECT_EQ(buffer[1], std::byte{0x02});
    EXPECT_EQ(buffer[2], std::byte{0x03});
    EXPECT_EQ(buffer[3], std::byte{0x04});
    EXPECT_EQ(buffer[4], std::byte{0x05});
}

/**
 * vector_reader 基础功能测试
 */
class VectorReaderTest : public ::testing::Test
{
protected:
    void SetUp() override
    {
        // 准备测试数据
        test_data_ = {std::byte{0x01},
                      std::byte{0x02},
                      std::byte{0x03},
                      std::byte{0x04},
                      std::byte{0x05},
                      std::byte{0x06},
                      std::byte{0x07},
                      std::byte{0x08}};
        reader_ = std::make_unique<vector_reader>(test_data_);
    }

    std::vector<std::byte> test_data_;
    std::unique_ptr<vector_reader> reader_;
};

/**
 * 测试 vector_reader 的基本读取功能
 */
TEST_F(VectorReaderTest, basic_read_operations)
{
    std::array<std::byte, 4> buffer{};
    reader_->read_bytes(buffer.data(), buffer.size());

    EXPECT_EQ(reader_->position(), 4);
    EXPECT_EQ(reader_->remaining_bytes(), 4);
    EXPECT_TRUE(reader_->has_data());

    EXPECT_EQ(buffer[0], std::byte{0x01});
    EXPECT_EQ(buffer[1], std::byte{0x02});
    EXPECT_EQ(buffer[2], std::byte{0x03});
    EXPECT_EQ(buffer[3], std::byte{0x04});
}

/**
 * 测试 vector_reader 的 span 读取功能
 */
TEST_F(VectorReaderTest, span_read_operations)
{
    std::array<std::byte, 3> buffer{};
    kp::span<std::byte> span_buffer(buffer.data(), buffer.size());

    reader_->read_bytes(span_buffer);

    EXPECT_EQ(reader_->position(), 3);
    EXPECT_EQ(buffer[0], std::byte{0x01});
    EXPECT_EQ(buffer[1], std::byte{0x02});
    EXPECT_EQ(buffer[2], std::byte{0x03});
}

/**
 * 测试 vector_reader 的字符串读取功能
 */
TEST_F(VectorReaderTest, string_read_operations)
{
    // 创建包含字符串的测试数据
    std::string test_string = "Hello";
    std::vector<std::byte> string_data;
    for (char c : test_string)
    {
        string_data.push_back(static_cast<std::byte>(c));
    }

    vector_reader string_reader(string_data);
    std::string result = string_reader.read_string(test_string.size());

    EXPECT_EQ(result, test_string);
    EXPECT_EQ(string_reader.position(), test_string.size());
}

/**
 * 测试 vector_reader 的边界检查
 */
TEST_F(VectorReaderTest, boundary_checks)
{
    // 读取所有数据
    std::array<std::byte, 8> buffer{};
    reader_->read_bytes(buffer.data(), buffer.size());

    EXPECT_EQ(reader_->position(), 8);
    EXPECT_EQ(reader_->remaining_bytes(), 0);
    EXPECT_FALSE(reader_->has_data());

    // 尝试读取更多数据应该抛出异常
    std::array<std::byte, 1> extra_buffer{};
    EXPECT_THROW(reader_->read_bytes(extra_buffer.data(), extra_buffer.size()), std::runtime_error);
}

/**
 * 测试 vector_reader 的错误处理
 */
TEST_F(VectorReaderTest, error_handling)
{
    // 测试空指针读取
    EXPECT_THROW(reader_->read_bytes(nullptr, 5), std::runtime_error);

    // 测试空指针但大小为0的情况（应该成功）
    EXPECT_NO_THROW(reader_->read_bytes(nullptr, 0));

    // 测试读取超出范围的数据
    EXPECT_THROW(reader_->read_bytes(nullptr, 100), std::runtime_error);

    // 测试读取超出范围的字符串
    EXPECT_THROW(reader_->read_string(100), std::runtime_error);
}

/**
 * 测试 vector_reader 的 seek 功能
 */
TEST_F(VectorReaderTest, seek_functionality)
{
    // 先读取一些数据
    std::array<std::byte, 2> buffer{};
    reader_->read_bytes(buffer.data(), buffer.size());
    EXPECT_EQ(reader_->position(), 2);

    // 回到开始位置
    reader_->seek(0);
    EXPECT_EQ(reader_->position(), 0);
    EXPECT_EQ(reader_->remaining_bytes(), 8);

    // 跳到中间位置
    reader_->seek(4);
    EXPECT_EQ(reader_->position(), 4);
    EXPECT_EQ(reader_->remaining_bytes(), 4);

    // 测试无效的 seek 位置
    EXPECT_THROW(reader_->seek(100), std::runtime_error);
}

/**
 * 测试 vector_reader 的移动构造
 */
TEST_F(VectorReaderTest, move_construction)
{
    std::vector<std::byte> data{std::byte{0xAA}, std::byte{0xBB}};
    vector_reader reader(std::move(data));

    std::array<std::byte, 2> buffer{};
    reader.read_bytes(buffer.data(), buffer.size());

    EXPECT_EQ(buffer[0], std::byte{0xAA});
    EXPECT_EQ(buffer[1], std::byte{0xBB});
}

/**
 * 测试空数据的处理
 */
TEST(SimpleIoEdgeCasesTest, empty_data_handling)
{
    // 空的 writer
    vector_writer empty_writer;
    EXPECT_EQ(empty_writer.bytes_written(), 0);
    EXPECT_EQ(empty_writer.position(), 0);
    EXPECT_TRUE(empty_writer.data().empty());

    // 空的 reader
    std::vector<std::byte> empty_data;
    vector_reader empty_reader(empty_data);
    EXPECT_EQ(empty_reader.position(), 0);
    EXPECT_EQ(empty_reader.remaining_bytes(), 0);
    EXPECT_FALSE(empty_reader.has_data());

    // 尝试从空 reader 读取数据应该抛出异常
    std::array<std::byte, 1> buffer{};
    EXPECT_THROW(empty_reader.read_bytes(buffer.data(), buffer.size()), std::runtime_error);
}

/**
 * 测试大数据处理
 */
TEST(SimpleIoPerformanceTest, large_data_handling)
{
    const size_t large_size = 1000000; // 1MB

    // 测试大数据写入
    vector_writer writer;
    std::vector<std::byte> large_data(large_size, std::byte{0x42});

    writer.write_bytes(large_data.data(), large_data.size());

    EXPECT_EQ(writer.bytes_written(), large_size);
    EXPECT_EQ(writer.position(), large_size);
    EXPECT_EQ(writer.data().size(), large_size);

    // 测试大数据读取
    vector_reader reader(writer.data());
    std::vector<std::byte> read_buffer(large_size);

    reader.read_bytes(read_buffer.data(), read_buffer.size());

    EXPECT_EQ(reader.position(), large_size);
    EXPECT_FALSE(reader.has_data());

    // 验证数据一致性
    for (size_t i = 0; i < large_size; ++i)
    {
        EXPECT_EQ(read_buffer[i], std::byte{0x42});
    }
}

/**
 * 测试概念约束的满足情况
 */
TEST(SimpleIoConceptsTest, concept_compliance)
{
    // 编译期验证概念满足情况
    static_assert(writer<vector_writer>);
    static_assert(reader<vector_reader>);
    static_assert(extended_writer<vector_writer>);
    static_assert(extended_reader<vector_reader>);
    static_assert(seekable_reader<vector_reader>);

    // 运行时验证基本功能
    vector_writer w;
    vector_reader r(w.data());

    EXPECT_TRUE(w.can_write(100));
    EXPECT_EQ(r.remaining_bytes(), 0);
}

/**
 * 测试 span_reader 的基本功能
 */
class SpanReaderTest : public ::testing::Test
{
protected:
    void SetUp() override
    {
        test_data = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
        reader = std::make_unique<span_reader>(test_data);
    }

    std::array<std::uint8_t, 8> test_data;
    std::unique_ptr<span_reader> reader;
};

TEST_F(SpanReaderTest, BasicReading)
{
    std::array<std::uint8_t, 4> buffer;
    reader->read_bytes(buffer);

    EXPECT_EQ(buffer[0], 0x01);
    EXPECT_EQ(buffer[1], 0x02);
    EXPECT_EQ(buffer[2], 0x03);
    EXPECT_EQ(buffer[3], 0x04);
    EXPECT_EQ(reader->position(), 4);
}

TEST_F(SpanReaderTest, ReadSpan)
{
    auto span_view = reader->read_span(4);
    EXPECT_EQ(span_view.size(), 4);
    EXPECT_EQ(static_cast<std::uint8_t>(span_view[0]), 0x01);
    EXPECT_EQ(static_cast<std::uint8_t>(span_view[3]), 0x04);
}

TEST_F(SpanReaderTest, ReadStringView)
{
    std::string test_str = "Hello";
    span_reader str_reader(kp::span<const std::byte>(
        reinterpret_cast<const std::byte *>(test_str.data()), test_str.size()));

    auto view = str_reader.read_string_view(5);
    EXPECT_EQ(view, "Hello");
}

TEST_F(SpanReaderTest, CanRead)
{
    EXPECT_TRUE(reader->can_read(4));
    EXPECT_TRUE(reader->can_read(8));
    EXPECT_FALSE(reader->can_read(9));

    std::array<std::uint8_t, 4> temp_buffer1{};
    reader->read_bytes(temp_buffer1);
    EXPECT_TRUE(reader->can_read(4));
    EXPECT_FALSE(reader->can_read(5));
}

TEST_F(SpanReaderTest, RemainingBytes)
{
    EXPECT_EQ(reader->remaining_bytes(), 8);

    std::array<std::uint8_t, 3> temp_buffer2{};
    reader->read_bytes(temp_buffer2);
    EXPECT_EQ(reader->remaining_bytes(), 5);
}

TEST_F(SpanReaderTest, Seek)
{
    reader->seek(4);
    EXPECT_EQ(reader->position(), 4);
    EXPECT_EQ(reader->remaining_bytes(), 4);

    std::array<std::uint8_t, 1> buffer;
    reader->read_bytes(buffer);
    EXPECT_EQ(buffer[0], 0x05);
}

/**
 * 测试 buffer_writer 的基本功能
 */
class BufferWriterTest : public ::testing::Test
{
protected:
    void SetUp() override
    {
        buffer.fill(0);
        writer = std::make_unique<buffer_writer>(buffer);
    }

    std::array<std::uint8_t, 16> buffer;
    std::unique_ptr<buffer_writer> writer;
};

TEST_F(BufferWriterTest, BasicWriting)
{
    std::array<std::uint8_t, 4> data = {0x01, 0x02, 0x03, 0x04};
    writer->write_bytes(data);

    EXPECT_EQ(buffer[0], 0x01);
    EXPECT_EQ(buffer[1], 0x02);
    EXPECT_EQ(buffer[2], 0x03);
    EXPECT_EQ(buffer[3], 0x04);
    EXPECT_EQ(writer->position(), 4);
    EXPECT_EQ(writer->bytes_written(), 4);
}

TEST_F(BufferWriterTest, WriteString)
{
    std::string test_str = "Hello";
    writer->write_string(test_str);

    EXPECT_EQ(writer->bytes_written(), 5);
    std::string result(reinterpret_cast<const char *>(buffer.data()), 5);
    EXPECT_EQ(result, "Hello");
}

TEST_F(BufferWriterTest, WriteStringView)
{
    std::string_view test_view = "World";
    writer->write_string_view(test_view);

    EXPECT_EQ(writer->bytes_written(), 5);
    std::string result(reinterpret_cast<const char *>(buffer.data()), 5);
    EXPECT_EQ(result, "World");
}

TEST_F(BufferWriterTest, CanWrite)
{
    EXPECT_TRUE(writer->can_write(16));
    EXPECT_FALSE(writer->can_write(17));

    std::array<std::uint8_t, 10> temp_data1{};
    writer->write_bytes(temp_data1);
    EXPECT_TRUE(writer->can_write(6));
    EXPECT_FALSE(writer->can_write(7));
}

TEST_F(BufferWriterTest, RemainingSpace)
{
    EXPECT_EQ(writer->remaining_space(), 16);

    std::array<std::uint8_t, 5> temp_data2{};
    writer->write_bytes(temp_data2);
    EXPECT_EQ(writer->remaining_space(), 11);
}

TEST_F(BufferWriterTest, FillBytes)
{
    writer->fill_bytes(std::byte{0xFF}, 8);

    for (std::size_t i = 0; i < 8; ++i)
    {
        EXPECT_EQ(buffer[i], std::uint8_t{0xFF});
    }
    EXPECT_EQ(writer->bytes_written(), 8);
}

TEST_F(BufferWriterTest, Seek)
{
    writer->write_bytes(std::array<std::uint8_t, 4>{0x01, 0x02, 0x03, 0x04});
    writer->seek(2);

    EXPECT_EQ(writer->position(), 2);
    writer->write_bytes(std::array<std::uint8_t, 2>{0xFF, 0xFE});

    EXPECT_EQ(buffer[0], 0x01);
    EXPECT_EQ(buffer[1], 0x02);
    EXPECT_EQ(buffer[2], 0xFF);
    EXPECT_EQ(buffer[3], 0xFE);
}

/**
 * 测试 stream_writer 的基本功能
 */
class StreamWriterTest : public ::testing::Test
{
protected:
    void SetUp() override
    {
        stream = std::make_unique<std::ostringstream>();
        writer = std::make_unique<stream_writer>(*stream);
    }

    std::unique_ptr<std::ostringstream> stream;
    std::unique_ptr<stream_writer> writer;
};

TEST_F(StreamWriterTest, BasicWriting)
{
    std::array<std::uint8_t, 4> data = {0x48, 0x65, 0x6C, 0x6C}; // "Hell"
    writer->write_bytes(data);

    EXPECT_EQ(writer->bytes_written(), 4);
    EXPECT_EQ(stream->str(), "Hell");
}

TEST_F(StreamWriterTest, WriteString)
{
    std::string test_str = "Hello World";
    writer->write_string(test_str);

    EXPECT_EQ(writer->bytes_written(), 11);
    EXPECT_EQ(stream->str(), "Hello World");
}

TEST_F(StreamWriterTest, WriteStringView)
{
    std::string_view test_view = "Test";
    writer->write_string_view(test_view);

    EXPECT_EQ(writer->bytes_written(), 4);
    EXPECT_EQ(stream->str(), "Test");
}

TEST_F(StreamWriterTest, CanWrite)
{
    EXPECT_TRUE(writer->can_write(100));
    EXPECT_TRUE(writer->can_write(1000));
}

/**
 * 测试 stream_reader 的基本功能
 */
class StreamReaderTest : public ::testing::Test
{
protected:
    void SetUp() override
    {
        stream = std::make_unique<std::istringstream>("Hello World Test");
        reader = std::make_unique<stream_reader>(*stream);
    }

    std::unique_ptr<std::istringstream> stream;
    std::unique_ptr<stream_reader> reader;
};

TEST_F(StreamReaderTest, BasicReading)
{
    std::array<std::uint8_t, 5> buffer;
    reader->read_bytes(buffer);

    std::string result(reinterpret_cast<const char *>(buffer.data()), 5);
    EXPECT_EQ(result, "Hello");
    EXPECT_EQ(reader->bytes_read(), 5);
}

TEST_F(StreamReaderTest, ReadString)
{
    auto str = reader->read_string(5);
    EXPECT_EQ(str, "Hello");
    EXPECT_EQ(reader->bytes_read(), 5);
}

TEST_F(StreamReaderTest, HasData)
{
    EXPECT_TRUE(reader->has_data());

    // 读取所有数据
    auto str = reader->read_string(16);
    EXPECT_FALSE(reader->has_data());
}

TEST_F(StreamReaderTest, CanRead)
{
    EXPECT_TRUE(reader->can_read(10));

    // 读取所有数据后
    reader->read_string(16);
    EXPECT_FALSE(reader->can_read(1));
}

/**
 * 测试零拷贝优化
 */
class ZeroCopyTest : public ::testing::Test
{
protected:
    void SetUp() override { test_data = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; }

    std::array<std::uint8_t, 8> test_data;
};

TEST_F(ZeroCopyTest, SpanReaderZeroCopy)
{
    span_reader reader(test_data);

    auto span1 = reader.read_span(4);
    auto span2 = reader.read_span(4);

    EXPECT_EQ(reinterpret_cast<const std::uint8_t *>(span1.data()), test_data.data());
    EXPECT_EQ(reinterpret_cast<const std::uint8_t *>(span2.data()), test_data.data() + 4);

    EXPECT_EQ(static_cast<std::uint8_t>(span1[0]), 0x01);
    EXPECT_EQ(static_cast<std::uint8_t>(span1[3]), 0x04);
    EXPECT_EQ(static_cast<std::uint8_t>(span2[0]), 0x05);
    EXPECT_EQ(static_cast<std::uint8_t>(span2[3]), 0x08);
}

TEST_F(ZeroCopyTest, BufferWriterZeroCopy)
{
    std::array<std::uint8_t, 16> buffer;
    buffer_writer writer(buffer);

    writer.write_bytes(test_data);

    auto written_span = writer.written_data();
    EXPECT_EQ(written_span.size(), 8);
    EXPECT_EQ(reinterpret_cast<const std::uint8_t *>(written_span.data()), buffer.data());

    auto remaining_span = writer.remaining_buffer();
    EXPECT_EQ(remaining_span.size(), 8);
    EXPECT_EQ(reinterpret_cast<const std::uint8_t *>(remaining_span.data()), buffer.data() + 8);
}